package com.zatech.cgnci.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zatech.cgnci.project.base.context.UserContext;
import com.zatech.cgnci.project.base.enums.ApprovalConfigEnum;
import com.zatech.cgnci.project.base.enums.BusinessScenariosEnum;
import com.zatech.cgnci.project.base.enums.OperationTypeEnum;
import com.zatech.cgnci.project.base.enums.ResponseCodeEnum;
import com.zatech.cgnci.project.base.exception.GlobalException;
import com.zatech.cgnci.project.base.utils.ConvertUtils;
import com.zatech.cgnci.project.base.utils.VerifyUtils;
import com.zatech.cgnci.project.dto.*;
import com.zatech.cgnci.project.entity.*;
import com.zatech.cgnci.project.mapper.CgnciAnnualInsurePlanMapper;
import com.zatech.cgnci.project.mapper.CgnciApprovalInfoMapper;
import com.zatech.cgnci.project.mapper.CgnciApprovalRecordMapper;
import com.zatech.cgnci.project.service.*;
import com.zatech.cgnci.project.vo.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 方案信息主表 服务实现类
 * </p>
 *
 * @author Generator
 * @since 2024-12-17
 */
@Service
public class CgnciAnnualInsurePlanServiceImpl extends ServiceImpl<CgnciAnnualInsurePlanMapper, CgnciAnnualInsurePlanDO> implements CgnciAnnualInsurePlanService {

    @Resource
    CgnciReinsureRiskService reinsureRiskService;
    @Resource
    CgnciAccessoryService accessoryService;
    @Resource
    IApprovalService approvalService;
    @Resource
    CgnciApprovalInfoMapper approvalInfoMapper;
    @Resource
    CgnciApprovalRecordMapper approvalRecordMapper;
    @Resource
    CgnciRiskService riskService;
    @Resource
    CgnciOperationLogsService cgnciOperationLogsService;
    @Resource
    CgnciApprovalRecordService approvalRecordService;

    @Override
    public IPage<CgnciAnnualInsurePlanPageVO> pageInsurePlan(CgnciAnnualInsurePlanQueryDTO dto) {
        List<Long> classBusinessIdS = new ArrayList<>();
        List<Long> subTypeBusinessIdS = new ArrayList<>();
        if (VerifyUtils.isNotEmpty(dto.getRiskClass())) {
            List<CgnciReinsureRiskDO> codeReinsureRiskDOs = reinsureRiskService.list(new LambdaQueryWrapper<CgnciReinsureRiskDO>()
                    .eq(CgnciReinsureRiskDO::getRiskClass, dto.getRiskClass()));
            if (VerifyUtils.isEmpty(codeReinsureRiskDOs)) {
                return new Page<>();
            }
            classBusinessIdS = codeReinsureRiskDOs.stream().map(CgnciReinsureRiskDO::getBusinessId).collect(Collectors.toList());
            dto.setInPlanIds(classBusinessIdS);
        }

        if (VerifyUtils.isNotEmpty(dto.getRiskSubType())) {
            List<CgnciReinsureRiskDO> nameReinsureRiskDOs = reinsureRiskService.list(new LambdaQueryWrapper<CgnciReinsureRiskDO>()
                    .eq(CgnciReinsureRiskDO::getRiskSubType, dto.getRiskSubType()));
            if (VerifyUtils.isEmpty(nameReinsureRiskDOs)) {
                return new Page<>();
            }
            subTypeBusinessIdS = nameReinsureRiskDOs.stream().map(CgnciReinsureRiskDO::getBusinessId).collect(Collectors.toList());
            dto.setInPlanIds(subTypeBusinessIdS);
        }

        if (VerifyUtils.isNotEmpty(dto.getRiskClass()) || VerifyUtils.isNotEmpty(dto.getRiskSubType())) {
            List<Long> inPlanIds = new ArrayList<>(CollectionUtils.intersection(classBusinessIdS, subTypeBusinessIdS));
            if (VerifyUtils.isEmpty(inPlanIds)) {
                return new Page<>();
            }
            dto.setInPlanIds(inPlanIds);
        }
        IPage<CgnciAnnualInsurePlanPageVO> page = this.baseMapper.pageInsurePlan(dto.toPage(), dto);
        page.getRecords().forEach(plan -> {
            List<CgnciReinsureRiskDO> list = reinsureRiskService.list(new LambdaQueryWrapper<CgnciReinsureRiskDO>().eq(CgnciReinsureRiskDO::getBusinessId, plan.getInPlanId()));
            plan.setRiskClass(list.stream().map(CgnciReinsureRiskDO::getRiskClass).collect(Collectors.joining(",")));
            plan.setRiskSubType(list.stream().map(CgnciReinsureRiskDO::getRiskSubType).collect(Collectors.joining(",")));
        });
        return page;
    }

    @Override
    public CgnciAnnualInsurePlanMainVO detail(Long inPlanId) {
        CgnciAnnualInsurePlanMainVO annualInsurePlanMainVO = new CgnciAnnualInsurePlanMainVO();
        // 基本信息
        CgnciAnnualInsurePlanDO annualInsurePlanDO = this.baseMapper.selectById(inPlanId);
        annualInsurePlanMainVO.setAnnualInsurePlanVO(ConvertUtils.convert(annualInsurePlanDO, CgnciAnnualInsurePlanVO.class));
        // 任务流程和镜像数据1对1
        CgnciApprovalInfoDO approvalInfoDO = approvalInfoMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalInfoDO>()
                .eq(CgnciApprovalInfoDO::getFormId, annualInsurePlanDO.getInPlanId())
                .eq(CgnciApprovalInfoDO::getFormNo, annualInsurePlanDO.getFormNo()));
        if (VerifyUtils.isNotEmpty(approvalInfoDO)) {
            annualInsurePlanMainVO.setApprovalInfoId(approvalInfoDO.getApprovalInfoId());
            annualInsurePlanMainVO.setTaskId(approvalInfoDO.getTaskId());
            annualInsurePlanMainVO.setTaskType(approvalInfoDO.getTaskType());
        }

        // 险种信息
        List<CgnciReinsureRiskDO> reinsureRiskList = reinsureRiskService.list(new LambdaQueryWrapper<CgnciReinsureRiskDO>().eq(CgnciReinsureRiskDO::getBusinessId, inPlanId));
        annualInsurePlanMainVO.setReinsureRiskVOList(ConvertUtils.convert(reinsureRiskList, CgnciReinsureRiskVO.class));

        // 文件信息
        List<CgnciAccessoryDO> accessoryList = accessoryService.list(new LambdaQueryWrapper<CgnciAccessoryDO>().eq(CgnciAccessoryDO::getBusinessId, inPlanId));
        annualInsurePlanMainVO.setAccessoryVOList(ConvertUtils.convert(accessoryList, CgnciAccessoryVO.class));
        return annualInsurePlanMainVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CgnciAnnualInsurePlanDO saveOrUpdateAnnualInsurePlan(CgnciAnnualInsurePlanSaveOrUpdateDTO updateDTO) {
        // 获取当前登录用户
        UserEntity user = UserContext.getUser();

        // 校验复制的险种最大净自留限额id
        CgnciAnnualInsurePlanDO checkPlan = this.getById(updateDTO.getAnnualInsurePlanUpdateDTO().getInPlanId());
        if (VerifyUtils.isEmpty(checkPlan)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "inPlanId有误");
        }
        // 只有已完成才能编辑
        if (!"0".equals(checkPlan.getStatus()) && !"2".equals(checkPlan.getStatus())) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "当前状态不能录入");
        }

        // 提交审核校验数据
        if (VerifyUtils.isNotEmpty(updateDTO.getFlowTaskType()) && "submit".equals(updateDTO.getFlowTaskType())) {
            // 校验年度唯一性，查询除了同一流程，不等于注销，录入中，退回录入中状态,当前年度的险种最大净自留限额
            List<CgnciAnnualInsurePlanDO> checkAnnualList = this.list(new LambdaQueryWrapper<CgnciAnnualInsurePlanDO>()
                    .notIn(CgnciAnnualInsurePlanDO::getFormNo, checkPlan.getFormNo())
                    .eq(CgnciAnnualInsurePlanDO::getAnnual, updateDTO.getAnnualInsurePlanUpdateDTO().getAnnual())
                    .notIn(CgnciAnnualInsurePlanDO::getStatus, Arrays.asList("0", "2", "4"))
                    .eq(CgnciAnnualInsurePlanDO::getIsMirror, "0"));
            if (VerifyUtils.isNotEmpty(checkAnnualList)) {
                throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "存在审核中或者已完成的相同年度险种最大净自留限额,请检查");
            }

            // 获取当前年度上一年度的险种最大净自留限额
            CgnciAnnualInsurePlanDO lastAnnualInsurePlan = this.getOne(new LambdaQueryWrapper<CgnciAnnualInsurePlanDO>()
                    .eq(CgnciAnnualInsurePlanDO::getIsMirror, "0")
                    .le(CgnciAnnualInsurePlanDO::getAnnual, updateDTO.getAnnualInsurePlanUpdateDTO().getAnnual())
                    .last("limit 1")
                    .orderByDesc(CgnciAnnualInsurePlanDO::getAnnual));
            if (VerifyUtils.isNotEmpty(lastAnnualInsurePlan)) {
                // 当前生效日期早于上一年度生效日期
                if (updateDTO.getAnnualInsurePlanUpdateDTO().getEffectiveTime().before(lastAnnualInsurePlan.getEffectiveTime())) {
                    throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "生效日期不能早于上一年度的生效日期");
                }
            }

            // 必须上传一份董事会决议文件
            List<CgnciAnnualInsurePlanSaveOrUpdateDTO.AccessoryDTO> accessoryDTOList = updateDTO.getAccessoryDTOList();
            if (VerifyUtils.isEmpty(accessoryDTOList)) {
                throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "必须上传一份董事会决议文件");
            }
            List<Long> accIds = accessoryDTOList.stream().map(CgnciAnnualInsurePlanSaveOrUpdateDTO.AccessoryDTO::getAccId).collect(Collectors.toList());
            List<CgnciAccessoryDO> ccessoryList = accessoryService.listByIds(accIds);
            CgnciAccessoryDO accessory = ccessoryList.stream().filter(acc -> "boardResolutionDoc".equals(acc.getAccType())).findFirst().orElse(null);
            if (VerifyUtils.isEmpty(accessory)) {
                throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "必须上传一份董事会决议文件");
            }
        }

        // 维护业务名称到工作台
        CgnciApprovalInfoDO approvalInfoDO = approvalInfoMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalInfoDO>()
                .eq(CgnciApprovalInfoDO::getFormId, updateDTO.getAnnualInsurePlanUpdateDTO().getInPlanId()));
        if (VerifyUtils.isEmpty(approvalInfoDO)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程不存在");
        }
        approvalInfoDO.setBusinessName(updateDTO.getAnnualInsurePlanUpdateDTO().getPlanName());
        approvalInfoMapper.updateById(approvalInfoDO);


        CgnciAnnualInsurePlanSaveOrUpdateDTO.CgnciAnnualInsurePlanUpdateDTO annualInsurePlanUpdateDTO = updateDTO.getAnnualInsurePlanUpdateDTO();
        CgnciAnnualInsurePlanDO annualInsurePlanDO = ConvertUtils.convert(annualInsurePlanUpdateDTO, CgnciAnnualInsurePlanDO.class);
        annualInsurePlanDO.setCreateUser(VerifyUtils.isEmpty(annualInsurePlanDO.getCreateUser()) ? user.getNameAndCode() : annualInsurePlanDO.getCreateUser());
        annualInsurePlanDO.setUpdateUser(user.getNameAndCode());
        this.saveOrUpdate(annualInsurePlanDO);

        // 险种信息
        List<CgnciAnnualInsurePlanSaveOrUpdateDTO.ReinsureRiskDTO> reinsureRiskDTOList = updateDTO.getReinsureRiskDTOList();
        if (VerifyUtils.isNotEmpty(reinsureRiskDTOList)) {
            List<CgnciReinsureRiskDO> reinsureRiskDOList = ConvertUtils.convert(reinsureRiskDTOList, CgnciReinsureRiskDO.class);
            reinsureRiskDOList.forEach(risk -> {
                if (VerifyUtils.isEmpty(risk.getInsuredAmountRmb()) && VerifyUtils.isEmpty(risk.getInsuredAmountDollar())) {
                    throw new GlobalException(ResponseCodeEnum.PARAMS_ILLEGAL, "最大净自留额必须填写人民币或者美元");
                }
                risk.setBusinessId(annualInsurePlanDO.getInPlanId());
                risk.setCreateUser(user.getNameAndCode());
                risk.setUpdateUser(user.getNameAndCode());
            });
            reinsureRiskService.saveOrUpdateBatch(reinsureRiskDOList);
        }

        // 文件信息
        List<CgnciAnnualInsurePlanSaveOrUpdateDTO.AccessoryDTO> accessoryDTOList = updateDTO.getAccessoryDTOList();
        if (VerifyUtils.isNotEmpty(accessoryDTOList)) {
            List<CgnciAccessoryDO> accessoryDOList = ConvertUtils.convert(accessoryDTOList, CgnciAccessoryDO.class);
            accessoryDOList.forEach(accessory -> {
                // 文件绑定业务数据
                accessory.setBusinessId(annualInsurePlanDO.getInPlanId());
            });
            accessoryService.saveOrUpdateBatch(accessoryDOList);
        }
        return annualInsurePlanDO;
    }

    @Override
    public CgnciAnnualInsurePlanDO nextEdit(Long inPlanId) {
        // 获取当前登录用户
        UserEntity user = UserContext.getUser();
        // 校验编辑的id
        CgnciAnnualInsurePlanDO checkAnnualInsurePlan = this.getById(inPlanId);
        if (VerifyUtils.isEmpty(checkAnnualInsurePlan)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "inPlanId有误");
        }

        // 只有已完成才能编辑
        if (!"3".equals(checkAnnualInsurePlan.getStatus())) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "当前状态不能编辑");
        }

        CgnciAnnualInsurePlanMainVO detailVO = this.detail(inPlanId);
        CgnciAnnualInsurePlanVO annualInsurePlanVO = detailVO.getAnnualInsurePlanVO();
        // 保存业务主表数据
        CgnciAnnualInsurePlanDO annualInsurePlanDO = ConvertUtils.convert(annualInsurePlanVO, CgnciAnnualInsurePlanDO.class);
        // 设置插入数据
        annualInsurePlanDO.setInPlanId(null);
        // 使用之前的流程编号绑定业务数据,目的是用来关联工作流,校验同一流程只能有一个在途的任务
        annualInsurePlanDO.setFormNo(checkAnnualInsurePlan.getFormNo());
        // 设置该数据为镜像数据
        annualInsurePlanDO.setIsMirror("1");
        annualInsurePlanDO.setStatus("0");
        annualInsurePlanDO.setIsEffective("0");
        annualInsurePlanDO.setCreateUser(user.getNameAndCode());
        annualInsurePlanDO.setCreateTime(new Date());
        annualInsurePlanDO.setUpdateUser(user.getNameAndCode());
        annualInsurePlanDO.setUpdateTime(new Date());
        this.save(annualInsurePlanDO);

        // 险种信息
        List<CgnciReinsureRiskVO> reinsureRiskVOList = detailVO.getReinsureRiskVOList();
        List<CgnciReinsureRiskDO> reinsureRiskDOList = ConvertUtils.convert(reinsureRiskVOList, CgnciReinsureRiskDO.class);
        if (VerifyUtils.isNotEmpty(reinsureRiskDOList)) {
            reinsureRiskDOList.forEach(risk -> {
                // 设置插入数据
                risk.setId(null);
                risk.setBusinessId(annualInsurePlanDO.getInPlanId());
                risk.setCreateUser(user.getNameAndCode());
                risk.setCreateTime(new Date());
                risk.setUpdateUser(user.getNameAndCode());
                risk.setUpdateTime(new Date());
            });
            reinsureRiskService.saveBatch(reinsureRiskDOList);
        }

        // 文件信息
        List<CgnciAccessoryVO> accessoryVOList = detailVO.getAccessoryVOList();
        if (VerifyUtils.isNotEmpty(accessoryVOList)) {
            List<CgnciAccessoryDO> accessoryList = new ArrayList<>();
            accessoryVOList.forEach(accessory -> {
                CgnciAccessoryDO accessoryDO = accessoryService.getById(accessory.getAccId());
                // 设置插入数据
                accessoryDO.setAccId(null);
                accessoryDO.setBusinessId(annualInsurePlanDO.getInPlanId());
                accessoryDO.setCreateUser(user.getNameAndCode());
                accessoryDO.setCreateTime(new Date());
                accessoryDO.setUpdateUser(user.getNameAndCode());
                accessoryDO.setUpdateTime(new Date());
                accessoryList.add(accessoryDO);
            });
            accessoryService.saveBatch(accessoryList);
        }
        return annualInsurePlanDO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submit(FlowTaskSubmitDTO flowTaskDTO) {
        UserEntity user = UserContext.getUser();
        CgnciAnnualInsurePlanDO annualInsurePlanDO = this.getById(flowTaskDTO.getFormId());
        // 校验年度承保计划是否存在
        if (VerifyUtils.isEmpty(annualInsurePlanDO)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR);
        }
        FlowTaskVO submit = approvalService.submit(flowTaskDTO);
        // 回调提交审核状态流程
        annualInsurePlanDO.setStatus(submit.getStatus());
        ApprovalRecordVO approvalRecordVo = approvalRecordService.getPreviousApprovalRecord(annualInsurePlanDO.getInPlanId());
        CgnciOperationLogsDTO operationLogsDTO = new CgnciOperationLogsDTO();
        operationLogsDTO.setBizNo(String.valueOf(annualInsurePlanDO.getInPlanId()));
        operationLogsDTO.setBizType(BusinessScenariosEnum.INSURANCE.getCode());
        if (approvalRecordVo.getGroupID().equals(ApprovalConfigEnum.APPROVAL_CONFIG_002.getGroupId())) {
            operationLogsDTO.setOperationType(OperationTypeEnum.SUBMIT_EDIT_INSURANCE_LIMIT.getCode());
        } else {
            operationLogsDTO.setOperationType(OperationTypeEnum.SUBMIT_INSURANCE_LIMIT.getCode());
        }
        operationLogsDTO.setCreator(user.getNameAndCode());
        cgnciOperationLogsService.saveLog(operationLogsDTO);
        /*String content = String.format("{%s}{%s}{%s} 流转至{%s}", BusinessStatusEnum.getDescByCode(submit.getStatus()), approvalRecordVo.getTaskType(), approvalRecordVo.getTaskId(), approvalRecordVo.getCurrentApproverAndName());
        operationLogsDTO.setContent(content);
        operationLogsDTO.setOperationType(OperationTypeEnum.TASK_TRANSFER.getCode());
        operationLogsDTO.setCreator("系统");
        cgnciOperationLogsService.saveLog(operationLogsDTO);*/
        this.updateById(annualInsurePlanDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approve(FlowTaskApprovalDTO flowTaskDTO) {
        UserEntity user = UserContext.getUser();
        // 校验年度承保计划是否存在
        CgnciAnnualInsurePlanDO annualInsurePlanDO = this.getById(flowTaskDTO.getFormId());
        if (VerifyUtils.isEmpty(annualInsurePlanDO)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR);
        }

        FlowTaskVO approve = approvalService.approve(flowTaskDTO);
        // 回调审批通过状态流程
        annualInsurePlanDO.setStatus(approve.getStatus());

        if (1 == approve.getIsEnd()) {
            annualInsurePlanDO.setIsMirror("0");
            annualInsurePlanDO.setIsEffective("1");

            // 审批通过之后,根据工作流配置的模块id(模块id可以有多个分组任务,比如新增任务和编辑任务)查询所有的业务数据,
            // 需要把最新审批通过的业务数据变为不是镜像数据,之前不是镜像数据的业务数据变更为镜像数据
            List<CgnciApprovalInfoDO> cgnciApprovalInfoDOS = approvalInfoMapper.selectList(new LambdaQueryWrapper<CgnciApprovalInfoDO>()
                    .eq(CgnciApprovalInfoDO::getFormNo, approve.getFormNo())
                    .eq(CgnciApprovalInfoDO::getStatus, "3")
                    .orderByDesc(CgnciApprovalInfoDO::getCreateTime)
                    .last("limit 2"));
            if (cgnciApprovalInfoDOS.size() == 2) {
                CgnciApprovalInfoDO firstApprovalInfo = cgnciApprovalInfoDOS.get(0);
                CgnciApprovalInfoDO secondApprovalInfo = cgnciApprovalInfoDOS.get(1);
                // 标记最近一条审批通过的业务数据为非镜像数据
                CgnciAnnualInsurePlanDO firstAnnualInsurePlan = this.getById(firstApprovalInfo.getFormId());
                firstAnnualInsurePlan.setIsMirror("0");
                firstAnnualInsurePlan.setIsEffective("1");
                this.updateById(firstAnnualInsurePlan);

                // 标记之后的一个业务数据为镜像数据
                CgnciAnnualInsurePlanDO secondAnnualInsurePlan = this.getById(secondApprovalInfo.getFormId());
                secondAnnualInsurePlan.setIsMirror("1");
                secondAnnualInsurePlan.setIsEffective("0");
                this.updateById(secondAnnualInsurePlan);
            }

        }
        this.updateById(annualInsurePlanDO);


        //审批通过后记录日志
        ApprovalRecordVO approvalRecord = approvalRecordService.getPreviousApprovalRecord(annualInsurePlanDO.getInPlanId());
        CgnciOperationLogsDTO operationLogsDTO = new CgnciOperationLogsDTO();
        operationLogsDTO.setBizNo(String.valueOf(annualInsurePlanDO.getInPlanId()));
        operationLogsDTO.setBizType(BusinessScenariosEnum.INSURANCE.getCode());
        if (approvalRecord.getGroupID().equals(ApprovalConfigEnum.APPROVAL_CONFIG_002.getGroupId())) {
            operationLogsDTO.setOperationType(OperationTypeEnum.EDIT_INSURANCE_LIMIT_PASS.getCode());
        } else {
            operationLogsDTO.setOperationType(OperationTypeEnum.ADD_INSURANCE_LIMIT_PASS.getCode());
        }
        operationLogsDTO.setContent(flowTaskDTO.getApproverOpinions());
        operationLogsDTO.setCreator(user.getNameAndCode());
        cgnciOperationLogsService.saveLog(operationLogsDTO);
        /*if (1 != approve.getIsEnd()) {
            String content = String.format("{%s}{%s}{%s} 流转至{%s}", BusinessStatusEnum.getDescByCode(approve.getStatus()), approvalRecord.getTaskType(), approvalRecord.getTaskId(), approvalRecord.getCurrentApproverAndName());
            operationLogsDTO.setContent(content);
            operationLogsDTO.setOperationType(OperationTypeEnum.TASK_TRANSFER.getCode());
            operationLogsDTO.setCreator("系统");
            cgnciOperationLogsService.saveLog(operationLogsDTO);
        }*/
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void back(FlowTaskBackDTO flowTaskDTO) {
        UserEntity user = UserContext.getUser();
        // 校验年度承保计划是否存在
        CgnciAnnualInsurePlanDO annualInsurePlanDO = this.getById(flowTaskDTO.getFormId());
        if (VerifyUtils.isEmpty(annualInsurePlanDO)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR);
        }
        FlowTaskVO back = approvalService.back(flowTaskDTO);
        // 回调审批通过状态流程
        annualInsurePlanDO.setStatus(back.getStatus());
        ApprovalRecordVO approvalRecord = approvalRecordService.getPreviousApprovalRecord(annualInsurePlanDO.getInPlanId());
        CgnciOperationLogsDTO operationLogsDTO = new CgnciOperationLogsDTO();
        operationLogsDTO.setBizNo(String.valueOf(annualInsurePlanDO.getInPlanId()));
        operationLogsDTO.setBizType(BusinessScenariosEnum.INSURANCE.getCode());
        if (approvalRecord.getGroupID().equals(ApprovalConfigEnum.APPROVAL_CONFIG_002.getGroupId())) {
            operationLogsDTO.setOperationType(OperationTypeEnum.EDIT_INSURANCE_LIMIT_BACK.getCode());
        } else {
            operationLogsDTO.setOperationType(OperationTypeEnum.ADD_INSURANCE_LIMIT_BACK.getCode());
        }
        operationLogsDTO.setContent(flowTaskDTO.getApproverOpinions());
        operationLogsDTO.setCreator(user.getNameAndCode());
        cgnciOperationLogsService.saveLog(operationLogsDTO);
        /*String content = String.format("{%s}{%s}{%s} 流转至{%s}", BusinessStatusEnum.getDescByCode(back.getStatus()), approvalRecord.getTaskType(), approvalRecord.getTaskId(), approvalRecord.getCurrentApproverAndName());
        operationLogsDTO.setContent(content);
        operationLogsDTO.setOperationType(OperationTypeEnum.TASK_TRANSFER.getCode());
        operationLogsDTO.setCreator("系统");
        cgnciOperationLogsService.saveLog(operationLogsDTO);*/
        this.updateById(annualInsurePlanDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void signOut(Long inPlanId) {
        // 获取当前登录用户
        UserEntity user = UserContext.getUser();
        CgnciAnnualInsurePlanDO annualInsurePlanDO = this.baseMapper.selectById(inPlanId);
        if (VerifyUtils.isEmpty(annualInsurePlanDO)) {
            throw new GlobalException(ResponseCodeEnum.PARAMS_ILLEGAL, "inPlanId有误");
        }
        // 判断当前状态是否为 录入中
        if (!"0".equals(annualInsurePlanDO.getStatus()) && !"2".equals(annualInsurePlanDO.getStatus())) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "当前状态不能注销");
        }
        approvalService.cancelTask(FlowTaskCancelDTO.builder().formId(String.valueOf(annualInsurePlanDO.getInPlanId())).formNo(annualInsurePlanDO.getFormNo()).build());

        // 回调提交审核状态流程
        annualInsurePlanDO.setStatus("4");
        ApprovalRecordVO previousApprovalRecord = approvalRecordService.getPreviousApprovalRecord(inPlanId);
        CgnciOperationLogsDTO operationLogsDTO = new CgnciOperationLogsDTO();
        operationLogsDTO.setBizNo(String.valueOf(annualInsurePlanDO.getInPlanId()));
        operationLogsDTO.setBizType(BusinessScenariosEnum.INSURANCE.getCode());
        if (previousApprovalRecord.getGroupID().equals(ApprovalConfigEnum.APPROVAL_CONFIG_002.getGroupId())) {
            operationLogsDTO.setOperationType(OperationTypeEnum.CANCEL_EDIT_INSURANCE_LIMIT.getCode());
        } else {
            operationLogsDTO.setOperationType(OperationTypeEnum.CANCEL_INSURANCE_LIMIT.getCode());
        }
        operationLogsDTO.setCreator(user.getNameAndCode());
        cgnciOperationLogsService.saveLog(operationLogsDTO);
        this.updateById(annualInsurePlanDO);
    }

    @Override
    public List<ApprovalRecordVO> log(Long inPlanId) {
        List<CgnciApprovalRecordDO> approvalRecordDOList = approvalRecordMapper.selectList(new LambdaQueryWrapper<CgnciApprovalRecordDO>().eq(CgnciApprovalRecordDO::getFormId, inPlanId));
        return ConvertUtils.convert(approvalRecordDOList, ApprovalRecordVO.class);
    }


    @Override
    public List<CgnciAnnualInsurePlanPolicyVO> listPlanPolicy(String annual, String riskSubTypeCodes) {
        // 优先根据承保年度所属的当前年度获取，如果所属的年度的‘年度承保政策’还没有录入，就获取前一年的‘年度承保政策’
        List<CgnciAnnualInsurePlanPolicyVO> result = new ArrayList<>();
        // 根据业务年度查询年度承保计划
        CgnciAnnualInsurePlanDO annualInsurePlanDO = this.getOne(new LambdaQueryWrapper<CgnciAnnualInsurePlanDO>()
                .eq(CgnciAnnualInsurePlanDO::getAnnual, annual)
                .eq(CgnciAnnualInsurePlanDO::getStatus, "3")
                .eq(CgnciAnnualInsurePlanDO::getIsEffective, "1")
                .eq(CgnciAnnualInsurePlanDO::getIsMirror, "0"));

        if (VerifyUtils.isEmpty(annualInsurePlanDO)) {
            annualInsurePlanDO = this.getOne(new LambdaQueryWrapper<CgnciAnnualInsurePlanDO>()
                    .eq(CgnciAnnualInsurePlanDO::getAnnual, String.format("%04d", Integer.parseInt(annual) - 1))
                    .eq(CgnciAnnualInsurePlanDO::getStatus, "3")
                    .eq(CgnciAnnualInsurePlanDO::getIsEffective, "1")
                    .eq(CgnciAnnualInsurePlanDO::getIsMirror, "0"));
        }

        if (VerifyUtils.isEmpty(annualInsurePlanDO)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "请录入" + annual + "年度最大净自留限额");
        }
        // 查询险种
        List<CgnciReinsureRiskDO> list = reinsureRiskService.list(new LambdaQueryWrapper<CgnciReinsureRiskDO>()
                .eq(CgnciReinsureRiskDO::getBusinessId, annualInsurePlanDO.getInPlanId()));
        list.forEach(reinsureRisk -> {
            CgnciRiskDO riskDO = riskService.getById(reinsureRisk.getRiskId());
            // 如果传值的险种包含的话,就返回
            if (riskSubTypeCodes.contains(riskDO.getRiskSubTypeCode())) {
                CgnciAnnualInsurePlanPolicyVO annualInsurePlanPolicyVO = CgnciAnnualInsurePlanPolicyVO.builder()
                        .riskClass(reinsureRisk.getRiskClass()).riskClassCode(reinsureRisk.getRiskClassCode())
                        .riskSubType(reinsureRisk.getRiskSubType()).riskSubTypeCode(reinsureRisk.getRiskSubTypeCode()).isExamine(riskDO.getIsExamine())
                        .insuredAmountRmb(reinsureRisk.getInsuredAmountRmb()).insuredAmountDollar(reinsureRisk.getInsuredAmountDollar()).build();
                result.add(annualInsurePlanPolicyVO);
            }
        });

        // 校验险种是否在result内
        String[] riskSubTypeCodeList = riskSubTypeCodes.split(",");
        for (String riskSubTypeCode : riskSubTypeCodeList) {
            CgnciRiskDO risk = riskService.getOne(new LambdaQueryWrapper<CgnciRiskDO>().eq(CgnciRiskDO::getRiskSubTypeCode, riskSubTypeCode));
            if (VerifyUtils.isEmpty(risk)) {
                throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "riskSubTypeCodes参数错误");
            }
            CgnciAnnualInsurePlanPolicyVO policy = result.stream().filter(value -> riskSubTypeCode.equals(value.getRiskSubTypeCode())).findFirst().orElse(null);
            if (VerifyUtils.isEmpty(policy)) {
                throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "所选的险种{" + risk.getRiskSubType() + "-" + risk.getRiskSubTypeCode() + "}不在" + annual + "年度最大净自留限额中");
            }
        }
        return result;
    }
}
